/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */

package com.iddaa.core.dao.impl;

import java.io.Serializable;
import java.lang.reflect.ParameterizedType;
import java.util.Collection;

import org.hibernate.LockMode;
import org.hibernate.SessionFactory;
import org.hibernate.criterion.DetachedCriteria;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.orm.hibernate3.HibernateTemplate;

import com.iddaa.core.dao.GenericDAO;

/**
 * 
 * @author aziz
 */
public abstract class AbstractHibernateDAO<T, ID extends Serializable> implements GenericDAO<T, ID> {

	protected Class<T> persistentClass;
	protected HibernateTemplate hibernateTemplate;

	@SuppressWarnings("unchecked")
	public AbstractHibernateDAO() {
		this.persistentClass = (Class<T>) ((ParameterizedType) getClass().getGenericSuperclass()).getActualTypeArguments()[0];
	}

	@Autowired
	public void setHibernateTemplate(SessionFactory sessionFactory) {
		this.hibernateTemplate = new HibernateTemplate(sessionFactory);
	}

	
	public T getById(ID id) {
		return (T) hibernateTemplate.get(persistentClass, id);
	}

	public T getById(ID id, boolean lock) {
		if (lock) {
			return (T) hibernateTemplate.get(persistentClass, id, LockMode.UPGRADE);
		} else
			return getById(id);
	}

	public T loadById(ID id) {
		return (T) hibernateTemplate.load(persistentClass, id);
	}

	@SuppressWarnings("unchecked")
	public ID save(T entity) {
		return (ID) hibernateTemplate.save(entity);
	}

	public void update(T entity) {
		hibernateTemplate.update(entity);
	}

	public void saveOrUpdate(T entity) {
		hibernateTemplate.saveOrUpdate(entity);
	}

	public void saveOrUpdateAll(Collection<T> entityCollection) {
		hibernateTemplate.saveOrUpdateAll(entityCollection);
	}

	public void delete(T entity) {
		hibernateTemplate.delete(entity);
	}

	public void deleteById(ID id) {
		hibernateTemplate.delete(loadById(id));
	}

	public void deleteAll(Collection<T> entityCollection) {
		hibernateTemplate.deleteAll(entityCollection);
	}

	@SuppressWarnings("unchecked")
	public Collection<T> loadAll() {
		return hibernateTemplate.findByCriteria(DetachedCriteria.forClass(persistentClass));
	}

	public T merge(T entity) {
		return hibernateTemplate.merge(entity);
	}

	@Override
	public void initialize(Object proxy) {
		hibernateTemplate.initialize(proxy);
	}

	@Override
	public void refresh(T entity) {
		hibernateTemplate.refresh(entity);
	}
	
}
